#include "constants.h";

XfMissionChapterExecute={
	private ["_chapter_succeeded"];
	diag_log "";
	diag_log "=========================================================================";
	diag_log "                             CHAPTER 1                                   ";
	diag_log "=========================================================================";
	diag_log "";
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Starting Chapter","_last_random_reinforcement","_random_reinf_diff","_reinforcement_power"];
	DM_Mission_ArtilleryVariables = [];
	DM_Mission_Chapter_CanRun = True;
	DM_Mission_Chapter_Runs = True;
	DM_Mission_Chapter_Success = 0;
	call XfMissionChapterSetup;
	_chapter_succeeded = false;
	if (!DM_Mission_Mission_CanRun) exitWith {diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Mission canceled!"];};

	_military_spot = DM_Chapter_Location;
	_military_pos = _military_spot select XF_MAP_LOCATION_CENTER;
	_military_pos_size = _military_spot select XF_MAP_LOCATION_SIZE;

	// Function to make Orlov flee with the Helicopter
	_fnc_helicopter_flee = {
		diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"chapter1.sqf","_fnc_helicopter_flee","Fleeing with Chopper"];
		_orlov = _this select 0;
		_grp = group _orlov;
		_helicopter = _this select 1;
		_destination = _this select 2;
		_initial_distance = _orlov distance _helicopter;
		_pos_smoke = _helicopter modelToWorld [0,6,1];
		_smokeShell = "smokeShell" createVehicle _pos_smoke;
		_smokeShell setDamage 1;
		_smokeShell = "smokeShell" createVehicle (getPos _helicopter);
		_smokeShell setDamage 1;
		_pos_smoke = _helicopter modelToWorld [0,-6,1];
		_smokeShell = "smokeShell" createVehicle _pos_smoke;
		_smokeShell setDamage 1;
		_pos_smoke = _helicopter modelToWorld [6,0,1];
		_smokeShell = "smokeShell" createVehicle _pos_smoke;
		_smokeShell setDamage 1;
		_pos_smoke = _helicopter modelToWorld [-6,0,1];
		_smokeShell = "smokeShell" createVehicle _pos_smoke;
		_smokeShell setDamage 1;
		
		diag_log Format["Dealer Escape: %1",_this];
		_orlov enableAI "MOVE";
		_orlov allowFleeing 0;
		_grp setBehaviour "CARELESS";
		_grp setCombatMode "GREEN";
		_grp setSpeedMode "FULL";
		sleep 1;
		_wp = _grp addWaypoint [(getPos _helicopter),3];
		_wp setWaypointType "MOVE";
		_wp setWaypointBehaviour "CARELESS";
		_wp setWaypointSpeed "FULL";
		_grp setCurrentWaypoint _wp; 
		_orlov domove (getPos _helicopter);
		sleep 5;
		_orlov domove (getPos _helicopter);
		sleep 5;
		_orlov domove (getPos _helicopter);
		sleep 15;
		_half_distance = _initial_distance / 2;
		if ((_orlov distance _helicopter) > _half_distance && ((_orlov distance _helicopter) > 20)) then {
			// We teleport Orlov out of the current building
			_new_pos = (getPos _orlov) findEmptyPosition[ _initial_distance / 4 , _half_distance];
			if (count _new_pos > 0) then {
				diag_log Format["Teleporting Dealer out of building: %1",_new_pos];
				_orlov setPos _new_pos;
			};
		};
		_i = 0;
		while {((_orlov distance _helicopter) > _half_distance) && _i < 20 && ((_orlov distance _helicopter) > 20) && alive _helicopter && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
			diag_log Format["Repeating move order: %1", (_orlov distance _helicopter)];
			_orlov domove (getPos _helicopter);
			sleep 5;
			_i = _i + 1;
		};
		if (! alive _helicopter) exitWith{};
		if ((_orlov distance _helicopter) >= 20) then {
			// We teleport Orlov near the helicopter
			_new_pos = (getPos _helicopter) findEmptyPosition[ 0 , 20];
			if (count _new_pos > 0) then {
				diag_log Format["Teleporting Dealer to helicopter: %1",_new_pos];
				_orlov setPos _new_pos;
			};
		};
		_helicopter lock false;
		_orlov setPos (_helicopter modelToWorld [0,6,0]);
		diag_log Format["Dealer in helicopter: %1",_helicopter];
		_orlov assignAsDriver _helicopter;
		_orlov moveinDriver _helicopter;
		_orlov allowFleeing 0;
		_helicopter engineOn true;
		_grp setBehaviour "CARELESS";
		_grp setCombatMode "BLUE";
		_grp setSpeedMode "FULL";
		_wp = _grp addWaypoint [_destination,200];
		_wp setWaypointType "MOVE";
		_wp setWaypointBehaviour "CARELESS";
		_wp setWaypointSpeed "FULL";
		_grp setCurrentWaypoint _wp; 
		_helicopter flyinHeight 200;
		// while {(((velocity _helicopter) distance [0,0,0]) < 0.2) && alive _helicopter } do {
		while {((driver _helicopter) != _orlov ) && alive _helicopter  && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
			sleep 0.5;
		};
		if (! alive _helicopter) exitWith{};
		sleep 4;
		(group _orlov) setBehaviour "CARELESS";
		(group _orlov) setSpeedMode "FULL";
		// We limit the helicopter movement to ascencional until it's high enough to not hit anything :)
		// And to give the player a chance to hit it ;)
		// diag_log Format["Dealer on the way: %1",_helicopter];
		while {(((getPos _helicopter) select 2) < 60)  && alive _helicopter && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
			_helicopter setVelocity [0,0,((((getPos _helicopter) select 2) min 10) max 1)];
			sleep 0.05;
		};
		(group _orlov) setBehaviour "CARELESS";
		(group _orlov) setSpeedMode "FULL";
		if (! alive _helicopter) exitWith{};
		while { alive (driver _helicopter) && alive _helicopter  && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
			(driver _helicopter) doMove _destination;
			sleep 5;
		};
	};

	// Function to make Orlov flee with a BRDM
	_fnc_brdm_flee = {
		diag_log Format["(%1)[%2]: %3: %4 %5",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Fleeing with BRDM", _this];
		_orlov = _this select 0;
		_grp = group _orlov;
		_destination = _this select 1;
		_test = _destination;
		_i_tries = 1;
		while { surfaceIsWater [(_destination select 0), (_destination select 1)]  && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
			_test = [_destination, _i_tries * 200] call XfGetRanPointCircle;
			if (count _test > 0) then {
				_destination = _test;
			};
			_i_tries = _i_tries + 1;
		};
		_orlov_pos = getPos _orlov;
		_start_pos = [];
		_non_road_pos = [];
		_non_road_height = 5000;
		_spot_tested = 0;
		_i_tries = 45;
		while { count _start_pos <= 0 && _i_tries > 0 && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
			_start_pos = [_orlov_pos, 1000, 700] call XfGetRanPointCircle;
			_spot_tested = _spot_tested + 1;
			_entities = _start_pos nearEntities [["Man","Air","Car","Motorcycle","Tank"],400];
			_has_players = false;
			{
				if (isPlayer (driver _x)) exitWith { _has_players = true; };
			} foreach _entities;
			if (_has_players) then {
				diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Nearby player",_start_pos];
				if (d_mission_debug_messages) then { [false,[Format["brdm_spot_%1",_spot_tested], _start_pos, "ICON", "ColorRed", [0.5,0.5],"",0,"hd_objective","",0.5]] call XfMissionMarker; };
				_start_pos = [];
			} else {
				if (count _start_pos > 0) then {
					_roads = _start_pos nearRoads 100;
					// We test there is not much water in between (the BRDM is amphibious, it can cope with a bit of water)
					_dir = [_orlov_pos, _start_pos] call XfDirTo;
					_steps = round((_orlov_pos distance _start_pos) / 70);
					_water_count = 0;
					for [{_i = 1 }, {_i < _steps}, {_i = _i + 1}] do {
						_step = _i * 70;
						_x = (_orlov_pos select 0) + (_step * sin _dir);
						_y = (_orlov_pos select 1) + (_step * cos _dir);
						//[false,[Format["brdm_spot_%1_%2",_spot_tested,_i], [_x,_y,0], "ICON", "ColorRed", [0.5,0.5],"",0,"mil_dot","",0.5]] call XfMissionMarker;
						if (surfaceIsWater [_x, _y]) then { _water_count = _water_count + 1; };
					};
					if (_water_count > 1) then {
						diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Too much water",_start_pos];
						if (d_mission_debug_messages) then { [false,[Format["brdm_spot_%1",_spot_tested], _start_pos, "ICON", "ColorRed", [0.5,0.5],"",0,"hd_objective","",0.5]] call XfMissionMarker; };
						_start_pos = [];
					} else {
						if (count _roads > 0) then {
							diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Found spot",_start_pos];
							if (d_mission_debug_messages) then { [false,[Format["brdm_spot_%1",_spot_tested], _start_pos, "ICON", "ColorGreen", [0.5,0.5],"",0,"hd_objective","",0.5]] call XfMissionMarker; };
						} else {
							diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","No roads",_start_pos];
							if (([_start_pos, 5] call XfGetSlope) <= 1 && (([_start_pos] call XfGetASLPos) select 2) <= _non_road_height) then {
								_non_road_pos = _start_pos;
								_non_road_height = ([_start_pos] call XfGetASLPos) select 2;
							};
							if (d_mission_debug_messages) then { [false,[Format["brdm_spot_%1",_spot_tested], _start_pos, "ICON", "ColorRed", [0.5,0.5],"",0,"hd_objective","",0.5]] call XfMissionMarker; };
							_start_pos = [];
						};
					};
				};
			};
			_i_tries = _i_tries - 1;
		};
		if (count _start_pos <= 0) then {
			if (d_mission_debug_messages) then { [false,[Format["brdm_spot_alt"], _non_road_pos, "ICON", "ColorGreen", [0.5,0.5],"",0,"hd_objective","",0.5]] call XfMissionMarker; };
			_start_pos = _non_road_pos;
		};
		if (count _start_pos > 0 && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun) then {
			diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Creating BRDMs",(side _orlov),_start_pos];
			_brdm_type = switch { d_enemy_side } do {
				default { "BRDM2_INS" };
			};
			// No UPS, No TaskPatrol, No TaskDefend.
			_vgrp = [_grp,_start_pos,[],[_brdm_type,_brdm_type],false,"", false] call XfMissionCreateVehicleGroup;
			diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Created group",(units _vgrp),_vgrp];
			_vgrp allowFleeing 0;
			_vgrp setBehaviour "CARELESS";
			_vgrp setCombatMode "RED";
			_vgrp setSpeedMode "FULL";
			for [{_i = (count (waypoints _vgrp)) - 1 }, {_i >= 0 }, {_i = _i - 1}] do {
				deleteWaypoint [_vgrp, _i];
			};
			
			if ((group (leader _vgrp)) != (group _orlov)) then {
				(units _vgrp) joinSilent (group _orlov);
				(group _orlov) selectLeader _orlov;
				_vgrp = (group _orlov);
			};
			
			_wp = _vgrp addWaypoint [_orlov_pos, 0];
			_wp setWaypointBehaviour "CARELESS";
			_wp setWaypointSpeed "FULL";
			_vgrp setCurrentWaypoint _wp;
			doStop _orlov;
			
			_brdms = [];
			_last_positions = [];
			{
				_vec = vehicle _x;
				if ((_vec isKindOf _brdm_type) && (_x == driver _vec)) then {
					if (!(_vec in _brdms)) then {
						_brdms set[count _brdms, _vec];
						_last_positions set [ count _last_positions, getPos _vec];
					};
					if (isNull _brdm) then { _brdm = _vec; };
					[_vec, _orlov_pos] spawn {
						_brdm = _this select 0;
						_pos = _this select 1;
						_last_pos = getPos _brdm;
						_i = 0;
						while { ((_brdm distance _pos) > 50) && alive _brdm && _i < 100 } do {
							if ((_last_pos distance (getPos _brdm)) < 10) then {
								(driver _brdm) doMove _pos;
							};
							_last_pos = getPos _brdm;
							sleep 5;
							_i = _i + 1;
						};
					};
				};
				_x call XfDisableAIScripts;
			} foreach units _vgrp;
			diag_log Format["(%1)[%2]: %3: %4: %5 (%6)",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","Created BRDM",_brdm,typeof _brdm];
			_driver = driver (_brdms select 0);
			diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","_fnc_brdm_flee","BRDM Moving",(_driver distance _orlov)];
			
			_nearest_brdm = objNull;
			_brdms_alive = true;
			while { isnull _nearest_brdm && _brdms_alive && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
				_entities = (getPos _orlov) nearEntities [[_brdm_type],40];
				if (count _entities > 0) then {
					_nearest_brdm = _entities select 0;
				};
				_brdms_alive = false;
				for [{_i = 0},{_i < count _brdms},{_i = _i + 1}] do {
					_brdm = _brdms select _i;
					_last_pos = _last_positions select _i;
					if (alive _brdm) then {
						_brdms_alive = true;
						// if (((getPos _brdm) distance _last_pos) < 10) then {
							// (driver _brdm) doMove 
						// };
					};
					_last_positions set [ _i, getPos _brdm];
				};
				sleep 3.543;
			};
			_driver = driver _nearest_brdm;
			if (((_nearest_brdm distance _orlov) <= 50) && alive _nearest_brdm) then {
				doStop _driver;
				sleep 2;
				_smokeShell = "smokeShell" createVehicle (getPos _nearest_brdm);
				_smokeShell setDamage 1;
				_pos_smoke = _nearest_brdm modelToWorld [0,6,1];
				_smokeShell = "smokeShell" createVehicle _pos_smoke;
				_smokeShell setDamage 1;
				_pos_smoke = _nearest_brdm modelToWorld [0,-6,1];
				_smokeShell = "smokeShell" createVehicle _pos_smoke;
				_smokeShell setDamage 1;
				_pos_smoke = _nearest_brdm modelToWorld [6,0,1];
				_smokeShell = "smokeShell" createVehicle _pos_smoke;
				_smokeShell setDamage 1;
				_pos_smoke = _nearest_brdm modelToWorld [-6,0,1];
				_smokeShell = "smokeShell" createVehicle _pos_smoke;
				_smokeShell setDamage 1;
				
				diag_log Format["Dealer Move to BRDM: %1",_nearest_brdm];
				_orlov enableAI "MOVE";
				_orlov allowFleeing 0;
				_grp setBehaviour "CARELESS";
				_grp setCombatMode "GREEN";
				_grp setSpeedMode "FULL";
				_initial_distance = (_driver distance _orlov);
				sleep 1;
				_wp = _grp addWaypoint [(getPos _nearest_brdm),3];
				_wp setWaypointType "MOVE";
				_wp setWaypointBehaviour "CARELESS";
				_wp setWaypointSpeed "FULL";
				_grp setCurrentWaypoint _wp; 
				_orlov domove (getPos _nearest_brdm);
				sleep 5;
				_orlov domove (getPos _nearest_brdm);
				sleep 5;
				_orlov domove (getPos _nearest_brdm);
				sleep 15;
				_half_distance = _initial_distance / 2;
				if ((_orlov distance _nearest_brdm) > _half_distance && ((_orlov distance _nearest_brdm) > 10)) then {
					// We teleport Orlov out of the current building
					_new_pos = (getPos _orlov) findEmptyPosition[ _initial_distance / 4 , _half_distance];
					if (count _new_pos > 0) then {
						diag_log Format["Teleporting Dealer out of building: %1",_new_pos];
						_orlov setPos _new_pos;
					};
				};
				_i = 0;
				while {((_orlov distance _nearest_brdm) > _half_distance) && _i < 10 && ((_orlov distance _nearest_brdm) > 10) && alive _nearest_brdm && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
					diag_log Format["Repeating move order: %1", (_orlov distance _nearest_brdm)];
					_orlov domove (getPos _nearest_brdm);
					sleep 5;
					_i = _i + 1;
				};
				if (! alive _nearest_brdm) exitWith{};

				// [_orlov] joinSilent (group (driver _nearest_brdm));
				_nearest_brdm lock false;
				_nearest_brdm lockDriver false;
				if ((_orlov distance _nearest_brdm) >= 10) then {
					// We teleport Orlov near the BRDM
					_new_pos = (getPos _nearest_brdm) findEmptyPosition[ 0 , 10];
					if (count _new_pos > 0) then {
						diag_log Format["Teleporting Dealer to BRDM: %1",_new_pos];
						_orlov setPos _new_pos;
					};
				};
				{
					unassignVehicle _x;
					sleep 1;
					_x leaveVehicle _nearest_brdm;
					sleep 2;
					deleteVehicle _x;
					sleep 0.5;
				} foreach crew _nearest_brdm;
				diag_log Format["Crew in _brdm: %1",crew _nearest_brdm];
				_nearest_brdm lockDriver false;
				while { vehicle _orlov == _orlov  && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
					_orlov setPos (_nearest_brdm modelToWorld [0,4,0]);
					diag_log Format["Dealer in _brdm: %1",_nearest_brdm];
					_orlov assignAsDriver _nearest_brdm;
					_orlov moveInDriver _nearest_brdm;
					sleep 2.2345;
				};
				diag_log Format["Orlov on board, fleeing to: %1", _destination];
				for [{_i = (count (waypoints _grp)) - 1 }, {_i >= 0 }, {_i = _i - 1}] do {
					deleteWaypoint [_grp, _i];
				};
				(driver _nearest_brdm) allowFleeing 0;
				_wp = _grp addWaypoint [_destination, 200];
				_wp setWaypointBehaviour "CARELESS";
				_wp setWaypointSpeed "FULL";
				_grp setCurrentWaypoint _wp;
				(driver _nearest_brdm) disableAI "TARGET";
				(driver _nearest_brdm) disableAI "AUTOTARGET";
				while { (((getPos _nearest_brdm) distance _destination) > 200) && alive _nearest_brdm  && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun} do {
					(driver _nearest_brdm) doMove _destination;
					sleep 5;
				};
			};
		};
	};
	
	_dealer_updated = false;
	_dealer_killed = false;
	_player_detected = false;
	_detected_updated = false;
	_dealer_fleeing = false;
	_brdm_fleeing = false;
	_enemy_initial_counts = ([_military_pos,_military_pos_size,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
	_unique_id = 0;
	_reinforcements = 3;
	_detected_time = time;
	_flee_destination = (call XfGetRanPointOuterAir);
	while {(DM_VIP distance _flee_destination) < 2500 && (FLAG_BASE distance _flee_destination) < 2500} do {
		_flee_destination = (call XfGetRanPointOuterAir);
	};
	_reinforcement_trigger = _enemy_initial_counts / 4;
	diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Entering the loop",[DM_VIP,DM_Helicopter,_flee_destination,_enemy_initial_counts,_reinforcement_trigger], Time];
	while {DM_Mission_Chapter_CanRun AND DM_Mission_Mission_CanRun} do {
		sleep 10;
		_enemy_counts = ([_military_pos,_military_pos_size,d_enemy_side] call XfMissionGetZoneSideCount) select 0;
		_dealer_killed = ["jip_dealer_killed",false] call XNetGetJIP;
		if (["jip_player_detected",false] call XNetGetJIP) then {_player_detected = true;};
		
		if (_player_detected and !_detected_updated) then {
			_detected_updated = true;
			"STR_MF_TARGETESCAPING" call XfMissionMessageToAll;
			[d_enemy_side,[_military_pos,_military_pos_size],"MEN",1] call XfMissionCallReinforcement;
			_detected_time = time;
		};
		// If half the soldiers are killed and the chopper is available: Flee with chopper
		If (_player_detected && (((time - _detected_time) > 60) && _enemy_counts <= (_enemy_initial_counts / 2)) && !_dealer_fleeing && (canMove DM_Helicopter)) then {
			// Orlov will try to flee
			diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Dealer Escpaing",[_player_detected,(time - _detected_time), _enemy_counts,(_enemy_initial_counts / 2), _dealer_fleeing, (canMove DM_Helicopter)], Time];
			hint "Dealer escaping";
			[DM_VIP,DM_Helicopter,_flee_destination] spawn _fnc_helicopter_flee;
			_dealer_fleeing = true;
		};
		// If half the soldiers are killed and the chopper is destroyed: Flee with BRDM
		if (!(canMove DM_Helicopter) && (_enemy_counts <= (_enemy_initial_counts * 0.7)) && alive DM_VIP && !_brdm_fleeing) then {
			// Orlov asks for extra reinforcement in order to be able to flee
			diag_log Format["(%1)[%2]: %3: %4: %5, %6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Dealer BRDM",[_player_detected,(canMove DM_Helicopter), _enemy_counts,(_enemy_initial_counts / 2),alive DM_VIP,_brdm_fleeing, _dealer_fleeing], Time];
			[d_enemy_side,[_military_pos,_military_pos_size],"MEN",1] call XfMissionCallReinforcement;
			[d_enemy_side,[_military_pos,_military_pos_size],"MEN",1] call XfMissionCallReinforcement;
			[DM_VIP,_flee_destination] spawn _fnc_brdm_flee;
			_dealer_fleeing = true;
			_brdm_fleeing = true;
		};
		if (_dealer_fleeing && alive DM_VIP) then {
			_VIP_Dest = DM_VIP distance _flee_destination;
			_VIP_DestMin = 3000;
			{
				if ((_x distance DM_VIP) < _VIP_DestMin) then {
					_VIP_DestMin = (_x distance DM_VIP);
				};
			} foreach playableUnits;
			// If the VIP is less than 200m from its dest or 2000m from any players and far away from the castle... it's lost
			if ((_VIP_Dest < 200) || (((DM_VIP distance _military_pos) > 1000) && (_VIP_DestMin > 2000))) then {
				// The dealer escaped
				["STR_MF_TARGETESCAPED", "Orlov"] call XfMissionMessageToAll;
				_chapter_succeeded = false;
				DM_Mission_Chapter_CanRun = false;
				sleep 10;
			};
		};
		if (_dealer_killed) then {
			_chapter_succeeded = true;
			DM_Mission_Chapter_CanRun = false;
			sleep 10;
		};
		// diag_log Format["(%1)[%2]: %3: %4: en:%5  kill:%6  det:%7  flee:%8",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Loop",_enemy_counts,_dealer_killed,_player_detected,_dealer_fleeing];
		If (DM_Mission_Chapter_CanRun AND _player_detected AND (_reinforcements > 0)) then {
			// If the player is detected and no reinforcement is on the way.. Then we send new troops in :)
			if ((_enemy_initial_counts - _enemy_counts) > _reinforcement_trigger) then {
				if (_unique_id == 0) then {
					// If the reinforcement function returns a value greater than 0, it means a reinforcement was created!
					_unique_id = [d_enemy_side,[_military_pos,_military_pos_size],"MEN",DM_Mission_RandomReinforcement] call XfMissionCallReinforcement;
					if ((_unique_id) > 0) then {
						diag_log Format["(%1)[%2]: %3: %4: reinf:%5, diff:%6, ini:%7, vec:%8",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Sending reinforcement",_reinforcements,_enemy_diff,_enemy_initial_counts];
						_reinforcements = _reinforcements - 1;
						// hint "Reinforcement";
					};
				};
			} else {
				_unique_id = 0;
			};
		};
	};
	sleep 15;
	if (DM_Mission_Mission_CanRun) then {
		if (_chapter_succeeded) then {
			call XfMissionChapterSuccess;
		} else {
			call XfMissionChapterFailure;
		};
	} else {
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Mission canceled!"];
	};
	
	_players_found = true;
	_enemy_count = 100;
	While {DM_Mission_Mission_CanRun && _enemy_count > 3 && _players_found} do {
		sleep 5;
		if (X_MP) then {
			_players_found = false;
			{
				if (([(getPos _x), _random_town_pos, 600] call XfPointInCircle) && isplayer _x) exitWith { _players_found = true; };
			}foreach playableUnits;
		} else {
			_players_found = ([(getPos player), _random_town_pos, 600] call XfPointInCircle);
		};
		_enemy_count = (([_random_town_pos,400,d_enemy_side] call XfMissionGetZoneSideCount) select 0);
		if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3: %4: player:%5  enemies:%6",diag_tickTime,"chapter1.sqf","XfMissionChapterExecute","Chapter End Check",_players_found,_enemy_count]; };
	};
	// Just in case a reinforcement is already on the way.
	call XfMissionCancelReinforcement;
	call XfMissionChapterCleanUp;
	DM_Mission_Chapter_Runs = False;
};

XfMissionChapterSetup={
	private ["_military_site","_military_pos","_military_pos_size","_troops_power","_troops_coeff","_grpSpecOps","_i"];
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Starting Initialization: Lord of War"];
	
	_military_site = [];
	_military_pos = [];
	_military_pos_size = 150;
	_pos_type = -1;
	_orlov_pos = [];
	_chopper_pos = [];
	_i_tries = 20;
	_dir = random 360;
	_helper = objNull;
	while { ((count _military_site) <= 0) && (_i_tries > 0) && DM_Mission_Mission_CanRun && DM_Mission_Chapter_CanRun } do {
		_military_site = [[XF_MAP_LOCATION_TYPE_MILITARY,XF_MAP_LOCATION_TYPE_MOUNTAIN]] call XfMissionGetRandomSpot;
		// diag_log Format["(%1)[%2]: %3: %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Picked up", _military_site];
		if ( count _military_site > 0 ) then {
			_military_pos = _military_site select XF_MAP_LOCATION_CENTER;
			_pos_type = _military_site select XF_MAP_LOCATION_TYPE;
			_military_pos_size = _military_site select XF_MAP_LOCATION_SIZE;
			if (_military_pos_size < 150) then { _military_pos_size = 150 };
			if (_military_pos_size > 250) then { _military_pos_size = 250 };
			_buildings_pos = [];
			_check_pos = [];
			if (_pos_type == XF_MAP_LOCATION_TYPE_MOUNTAIN) then {
				_i_tries2 = 10;
				while { (count _buildings_pos <= 0) && (_i_tries2 > 0) } do {
					_check_pos = ([_military_pos, (_military_pos_size / 3)] call XfGetRanPointCircle);
					if (count _check_pos > 0) then {
						_check_pos = _check_pos findEmptyPosition[0 , (_military_pos_size * 0.5), "Barrack2"];
					};
					if (count _check_pos > 0) then {
						_buildings_pos = [_check_pos];
						_helper = "Barrack2" createVehicleLocal _check_pos;
						_dir = random 360;
						_helper setDir _dir;
					};
					_i_tries2 = _i_tries2 - 1;
				};
			} else {
				_buildings_pos = [_military_pos,_military_pos_size,"HIDE"] call XfMissionBuildingAreaPosASL;
			};
			if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Found positions",(_buildings_pos)]; };
			if ((count _buildings_pos) >= 0) then {
				// diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Checking building positions",(count _buildings_pos)];
				{
					_spot = +_x;
					_spot set [2, 0];
					_check_pos = [];
					if ((_spot distance _military_pos) <= (_military_pos_size * 0.85)) then {
						// diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Checking building positions",(count _buildings_pos)];
						// We need to find a spot for something bigger than the chopper for safety... it's arma :)
						_chopper_pos = [];
						_i_tries2 = 12;
						_check_pos = _spot;
						while { ( count _chopper_pos <= 0) && _i_tries2 > 0 } do {
							if (count _check_pos > 0) then {
								_chopper_pos = _check_pos findEmptyPosition[ 20 , (_military_pos_size * 0.5), "Mi17_Civilian"];
								// The following check makes sure the area is really big enough...
								// diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Checking Chopper Position",_chopper_pos];
								if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Testing Empty Spot",[_i_tries2, _check_pos, _chopper_pos]];};
								if (count _chopper_pos > 0) then {
									_chopper_pos = (_chopper_pos isflatempty [
													8,	//--- Minimal distance from another object
													0,				//--- If 0, just check position. If >0, select new one
													0,				//--- Max gradient
													8,	//--- Gradient area
													0,				//--- 0 for restricted water, 2 for required water,
													false,				//--- True if some water can be in 25m radius
													FLAG_BASE		//--- Ignored object
													]);
									if (count _chopper_pos > 0) then {
										_slope = ([[_chopper_pos select 0,_chopper_pos select 1, 0], 8] call XfGetSlope);
										if (_slope > 6) then {
											if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Slope too steep",[_i_tries2, _chopper_pos, _slope]];};
											_chopper_pos = [];
										};
									};									
								} else {
									// We give up quicker on spots with low space
									_i_tries2 = _i_tries2 - 1;
								};
							} else {
								_chopper_pos = [];
							};
							// We move around the position to find another suitable spot.
							_check_pos = [_spot, (30 + (30 / _i_tries))] call XfGetRanPointCircle;
							_i_tries2 = _i_tries2 - 1;
						};
						if (count _chopper_pos > 0) ExitWith {
							_orlov_pos = _x;
							if (_pos_type == XF_MAP_LOCATION_TYPE_MOUNTAIN) then {
								_orlov_pos = _check_pos;
							};
							_chopper_pos set [2, 0.5];
							diag_log Format["(%1)[%2]: %3; %4 ( %5, %6 )",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Found suitable building + chopper spot", _orlov_pos, _chopper_pos];
						};
					} else {
						if (d_mission_debug_messages) then { diag_log Format["(%1)[%2]: %3; %4: %5",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Building position too far",[_spot,(_spot distance _military_pos),_military_pos_size]];};
					};
				} foreach _buildings_pos;
				if (count _chopper_pos <= 0) then {
					diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Failed to find suitable building + chopper spot"];
					_military_site = [];
				};
			} else {
				diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","No enterable building"];
				_military_site = [];
			};
		} else {
			_military_site = [];
		};
		_i_tries = _i_tries - 1;
		if (!isnull _helper) then {
			deleteVehicle _helper;
		};
	};
	if (!isnull _helper) then {
		deleteVehicle _helper;
	};
	if ((count _military_site) <= 0) exitWith {"STR_MF_RANDOMSITEFAILED" call XfMissionMessageToAll; DM_Mission_Mission_CanRun = false; DM_Mission_Chapter_CanRun = false;};
	_military_pos_name = _military_site select XF_MAP_LOCATION_DISPLAYNAME;
	
	DM_Chapter_Location = _military_site;
	DM_Chapter_Position = _military_pos;
	
	if (_pos_type == XF_MAP_LOCATION_TYPE_MOUNTAIN) then {
		_barrack = ["Barrack2",[_orlov_pos,_dir],"REGISTER",[]] call XfMissionCreateMissionObject;
		_buildings_pos = [_orlov_pos,_military_pos_size,"HIDE"] call XfMissionBuildingAreaPosASL;
		if (count _building_pos > 0) then {
			_orlov_pos = _building_pos call XfRandomArrayVal;
		} else {
			_orlov_pos = [];
		};
		diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSetup","Failed to find suitable building + chopper spot"];
	};
	if ((count _orlov_pos) <= 0) exitWith {"STR_MF_RANDOMTARGETFAILED" call XfMissionMessageToAll; DM_Mission_Mission_CanRun = false; DM_Mission_Chapter_CanRun = false;};

	// This indicates where the mission takes place
	[_military_pos,_military_pos_size,_military_pos_name] call XfMissionCurrentPosition;
	
	_teleporter = [_military_pos] call XfMissionRandomStartTeleporter;
	// If no spot found, we get back an empty position.
	if (count (_teleporter select 0) > 0) then {
		[false,["chapter1_start_position",(_teleporter select 0), "ICON", "ColorBlue", [1,1],"",(_teleporter select 1),"hd_start","",1]] call XfMissionMarker;
	};

	// The marker which indicates the war zone. We increase it a lot, because they need to patrol all around the zone.
	[false,["chapter1_military_zone", _military_pos, "ELLIPSE", "ColorRed", [(_military_pos_size * 2.5),(_military_pos_size * 2.5)],"",0,"","BDiagonal",0.5]] call XfMissionMarker;
	[false,["chapter1_military_position",_military_pos, "ICON", "ColorRed", [1,1],_military_pos_name,0,"hd_objective","",0.6]] call XfMissionMarker;
	
	["jip_dealer_killed",false] call XNetSetJIP;
	_grp = [d_enemy_side] call x_creategroup;
	["Functionary1",_grp,_orlov_pos,"ASSASSINATE",["STR_MF_M_LORD_KILLED","jip_dealer_killed"],"doStop this; this disableAI ""MOVE"";"] call XfMissionCreateMissionUnit;
	DM_VIP = leader _grp;
	DM_VIP setPosASL _orlov_pos;
	DM_VIP addWeapon "AKS_74_U";
	DM_VIP addMagazine "30Rnd_545x39_AK";
	DM_VIP addMagazine "30Rnd_545x39_AK";
	DM_VIP addMagazine "30Rnd_545x39_AK";
	DM_VIP addMagazine "smokeShell";
	DM_VIP addMagazine "smokeShell";
	DM_VIP disableAI "MOVE";
	DM_VIP call XfDisableAIScripts;
	
	// player setPos _chopper_pos;
	// sleep 10;
	_heli_type = switch { d_own_side } do {
		case "EAST": { "Mi17_CDF" };
		default { "Mi17_Ins" };
	};
	_slope = ([_chopper_pos, 5] call XfGetSlope);
	_chopper_dir = 0;
	if (_slope > 0.7) then {
	// if (true) then {
		_helper = "Land_coneLight" createVehicleLocal _chopper_pos;
		_helper setVelocity [0,0,0];
		_pos_asl = getPosASL _helper;
		sleep 2;
		deleteVehicle _helper;
		_pos_asl set [2, ((_pos_asl select 2) + (_slope) - 5)];
		// _concrete = ["Land_ConcreteBlock",[_chopper_pos,0],"REGISTER",[]] call XfMissionCreateMissionObject;
		_concrete = ["land_nav_pier_c_90",[_chopper_pos,0],"REGISTER",[]] call XfMissionCreateMissionObject;
		_concrete setPosASL _pos_asl;
		_concrete setVectorUp [0,0,0];
		_ladder_pos = _pos_asl;
		_ladder_pos set[1, (_ladder_pos select 1) - 10.5];
		_ladder_pos set[2, (_ladder_pos select 2) + 2.7];
		_ladder = ["Land_ladder_half",[_ladder_pos,0],"REGISTER",[]] call XfMissionCreateMissionObject;
		_ladder setPosAsl _ladder_pos;
		sleep 2;
		_chopper_pos = _pos_asl;
		_chopper_pos set[1, (_chopper_pos select 1) + 8];
		// _chopper_pos set[1, (_chopper_pos select 1) - 5];
		_chopper_pos set[2, (_chopper_pos select 2) + 8];
		_helper = "Land_coneLight" createVehicleLocal _chopper_pos;
		_helper setPosASL _chopper_pos;
		sleep 5;
		_chopper_pos = getPos _helper;
		_chopper_pos set[2, (_chopper_pos select 2) + 1];
		deleteVehicle _helper;
		_chopper_dir = 45;
	};

	DM_Helicopter = [_heli_type,[_chopper_pos,_chopper_dir],"REGISTER",[]] call XfMissionCreateMissionObject;
	DM_Helicopter allowDamage false;
	DM_Helicopter lock true;
	for [{_i = 0},{_i < 20},{_i = _i + 1}] do {
		DM_Helicopter setVelocity [0,0,0];
		sleep 0.5;
	};
	DM_Helicopter spawn {
		sleep 180;
		_this allowDamage true;
	};
	// The trigger which will send reinforcement when the player is detected!
	["jip_player_detected",false] call XNetSetJIP;
	[_military_pos,_military_pos_size * 3,d_own_side,d_enemy_side,"jip_player_detected"] call XfMissionSideDetected;
	
	_power = DM_Mission_EnemyPower;
	if (_power < 1) then {_power = 1};
	_power = _power * 2;
	// Spawns groups of specops in Rog's Castle with the castle as operating zone. They'll search buildings for enemies.
	for [{_i=0}, {_i<_power}, {_i=_i+1}] do {
		_grpSpecOps = [d_enemy_side,[_military_pos,_military_pos_size],["chapter1_military_zone","noveh","aware","red","buildings"],1] call XfMissionCreateFootmenGroup;
	};
	// This group will simply wait for the player near the helicopter :)
	_grpSpecOps = [d_enemy_side,[(getPos DM_Helicopter),25],["chapter1_military_zone","noveh","aware","red","ambush2"],1] call XfMissionCreateFootmenGroup;

	["KillTheDealer","STR_MF_M_LORD_TASK_KILL", ["STR_MF_M_LORD_TASK_KILL_DESC",_military_pos_name],"",[],"Created"] call XfMissionTask;
	
	// This will create snipers automatically if selected in the mission setup
	[d_enemy_side,[_military_pos,_military_pos_size],DM_Mission_Snipers] call XfMissionCreateSnipersArea;
	// This will create air support automatically if selected in the mission setup
	[d_enemy_side,[_military_pos,_military_pos_size],DM_Mission_AirSupport] call XfMissionCallAirSupport;
};

XfMissionChapterSuccess={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterSuccess","Starting"];
	"STR_MF_TARGETKILLED" call XfMissionMessageToAll;
	DM_Mission_Chapter_Success = 1;
};

XfMissionChapterFailure={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterFailure","Starting"];
	"STR_MF_MISSIONFAILURE1" call XfMissionMessageToAll;
	DM_Mission_Chapter_Success = -1;
};

// Self-explanatory
XfMissionChapterCleanUp={
	diag_log Format["(%1)[%2]: %3; %4",diag_tickTime,"chapter1.sqf","XfMissionChapterCleanUp","Starting"];
	// Giving an empty position places the teleporter back to the hangar, closing the hangar.
	[[],0] call XfMissionPlaceStartTeleporter;
	[] call XfMissionCleanMarkers;
	[] call XfMissionCleanTriggers;
	[] call XfMissionCleanTasks;
};

DM_Mission_Chapter_Compiled = true;